<template>
  <text :style="`color: ${props.color};`">
    {{ preTxt }}{{ d > 0 ? `${d}天` : '' }}{{ padNumber(h) }}小时{{ padNumber(m) }}分{{ padNumber(s) }}秒
  </text>
</template>

<script lang="ts" setup>
import { onMounted, computed, ref, watch } from 'vue'
// import { loginSysTime } from '@/api/login';

/************************变量定义相关***********************/
const emit = defineEmits<{
  end: []
  remind: []
  change: [Date]
}>()

const props = withDefaults(
  defineProps<{
    expireTime?: string // 到期时间 yyyy-MM-dd HH:mm:ss
    preTxt?: string // 前置文本
    remind?: number // 剩余多久提醒（单位：秒）
    color?: string // 文字颜色
  }>(),
  {
    preTxt: '',
    color: '#000'
  }
)

const expireTime = ref<Date | string>() // 到期时间（苹果手机不识别横线）
const curTime = ref<Date | string>() // 当前时间
const times = ref(0) // 剩余次数

/************************组件生命周期相关*********************/
onMounted(async () => {
  synTime()
})

/************************监听相关*****************************/
watch(
  () => props.expireTime,
  () => {
    expireTime.value = props.expireTime ? new Date(props.expireTime.replaceAll('-', '/')) : ''
  },
  { immediate: true }
)

/************************计算属性相关*************************/
const d = computed(() => {
  if (!(expireTime.value instanceof Date) || !(curTime.value instanceof Date)) {
    return 0
  }

  return Math.floor((expireTime.value.getTime() - curTime.value.getTime()) / 1000 / 60 / 60 / 24)
})
const h = computed(() => {
  if (!(expireTime.value instanceof Date) || !(curTime.value instanceof Date)) {
    return 0
  }
  return Math.floor((((expireTime.value as Date).getTime() - (curTime.value as Date).getTime()) / 1000 / 60 / 60) % 24)
})
const m = computed(() => {
  if (!(expireTime.value instanceof Date) || !(curTime.value instanceof Date)) {
    return 0
  }
  return Math.floor((((expireTime.value as Date).getTime() - (curTime.value as Date).getTime()) / 1000 / 60) % 60)
})
const s = computed(() => {
  if (!(expireTime.value instanceof Date) || !(curTime.value instanceof Date)) {
    return 0
  }
  return Math.floor((((expireTime.value as Date).getTime() - (curTime.value as Date).getTime()) / 1000) % 60)
})

/************************事件相关*****************************/
// 数字前面补零
function padNumber(num: number) {
  if (num < 0) {
    return '00'
  }
  return num.toString().padStart(2, '0')
}

/**
 * 同步服务器时间
 * 每隔30秒同步一次服务器时间；30秒内使用本地浏览器计时；30秒内会有误差，但影响不大
 */
async function synTime() {
  // 如果没有过期时间，继续等待
  if (!(expireTime.value instanceof Date)) {
    setTimeout(synTime, 1000)
    return
  }

  // 每间隔30秒同步一次服务器时间
  if (times.value <= 0) {
    times.value = 30
    // let { data } = await loginSysTime();
    curTime.value = new Date()
    //console.log('服务时间：', data.replaceAll('-', '/'))
  } else {
    curTime.value = new Date((curTime.value as Date).getTime() + 1000)
    times.value--
    //console.log('本地时间：', curTime.value, !expireTime.value ? '-' : Math.floor(((expireTime.value.getTime() - curTime.value.getTime()) / 1000 ) % 60), s.value)
  }
  emit('change', curTime.value)

  // 如果有提醒，触发提醒事件
  if (props.remind) {
    if (curTime.value.getTime() + props.remind * 1000 >= expireTime.value.getTime()) {
      // console.log('倒计时事件：remind', curTime.value, expireTime.value)
      emit('remind')
    }
  }

  // 如果时间已到，触发事件，让上层处理
  if (curTime.value.getTime() >= expireTime.value.getTime()) {
    // console.log('倒计时事件：end', curTime.value, expireTime.value)
    emit('end')
    return
  }

  setTimeout(synTime, 1000)
  return
}
</script>

<style lang="scss" scoped></style>
